package com.fingard.dsp.bank.directbank.tzb01;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directConfig.TaskTimerSet;
import com.fingard.dsp.bank.directbank.bankInterface.IScheduleTask;
import com.fingard.io.FileHelper;
import com.fingard.net.*;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.util.SmbFileUtil;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * Created by F on 2019/4/17.
 */
public class TZB01ScheduleTask extends TZB01Base implements IScheduleTask {
    private String receiptSaveToMainDir = "";

    @Override
    public void execTask(TaskTimerSet timerSet) {
        if (timerSet.taskNameList.toLowerCase().equals("pushreceipt")) {
            pushReceipt();
        }
    }

    private void pushReceipt() {
        try {
            receiptSaveToMainDir = FGBiz.dspCenter.dspSet.receiptMainDir;
            if (StringHelper.hasAnyChar(receiptSaveToMainDir)) {
                if (StringHelper.hasAnyChar(FGBiz.dspCenter.dspSet.receiptShareDir)) {
                    if (StringHelper.hasAnyChar(FGBiz.dspCenter.dspSet.receiptPushServerUrl)) {
                        getStatement();
                    } else {
                        WriteBankLogLn("DSPSystem未配置回单文件推送地址");
                    }
                } else {
                    WriteBankLogLn("DSPSystem未配置回单文件共享目录");
                }
            } else {
                WriteBankLogLn("DSPSystem未配置回单文件下载保存主目录");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    private void getStatement() {
        String uploadType = SmbFileUtil.getUploadType();
        try {
            String receiptDataPath = FGBiz.dspCenter.dataDirPath + File.separator + "datafile" + File.separator + bankFront.bankCode + File.separator
                    + "receiptdatafile" + File.separator + Format.Date8Format.format(new Date());
            File receiptDataDir = new File(receiptDataPath);
            File[] actList = receiptDataDir.listFiles();
            if (actList == null || actList.length == 0) {
                WriteBankLogLn("没有需要下载电子回单的账号文件夹");
            } else {
                for (File actFile : actList) {
                    File[] receiptMonthList = actFile.listFiles();
                    //一个账号下面当天各月份的回单汇总，会有重复
                    if (receiptMonthList != null && receiptMonthList.length != 0) {
                        //处理一个回单处理文件
                        for (File receiptdateFile : receiptMonthList) {
                            int tmpFileCount = 0;
                            //记录成功处理回单文件的名称
                            StringBuilder uploadRecord = new StringBuilder();
                            StringBuilder json = new StringBuilder();
                            json.append("transType=downloadreceipt&data={\"rows\":[");
                            String receiptdatetent = FileHelper.readFileText(receiptdateFile.getAbsolutePath(), getCharset());
                            String[] receiptInfolist = receiptdatetent.split("\\n");
                            //key为日期_账号
                            Map<String, Map<String, String[]>> receiptNoMap = new HashMap<String, Map<String, String[]>>();
                            if (receiptMonthList != null && receiptMonthList.length != 0) {
                                for (String receiptInfo : receiptInfolist) {
                                    //交易单号|经办日期|账号|原交易流水号|交易金额|经办柜员|
                                    String[] receiptInfoArr = receiptInfo.split("\\|");
                                    if (receiptInfoArr.length != 6) {
                                        WriteBankLogLn("当前行内容异常：" + receiptInfo);
                                        continue;
                                    }
                                    String key = receiptInfoArr[1] + "_" + receiptInfoArr[2];
                                    if (receiptNoMap.keySet().contains(key)) {
                                        receiptNoMap.get(key).put(receiptInfoArr[0], receiptInfoArr);
                                    } else {
                                        Map<String, String[]> tmpMap = new HashMap<String, String[]>();
                                        tmpMap.put(receiptInfoArr[0], receiptInfoArr);
                                        receiptNoMap.put(key, tmpMap);
                                    }
                                }
                            } else {
                                continue;
                            }
                            //下载当前回单汇总文件中未下载的回单文件
                            Map<String, File> receiptList = downloadReceipt(receiptNoMap);
                            for (Map.Entry<String, File> fileEntry : receiptList.entrySet()) {
                                String key = fileEntry.getKey();
                                String[] keys = key.split("_");
                                File receipt = fileEntry.getValue();
                                String tmpByDate = keys[0].substring(0, 6) + "/" + keys[0].substring(6, 8)
                                        + "/" + bankFront.bankCode + "/" + keys[1] + "/";
                                int result = -1;
                                if (receipt.exists()) {
                                    if ("smb".equals(uploadType)) {
                                        WriteBankLogLn("正在上传文件至共享目录:" + FGBiz.dspCenter.dspSet.receiptShareDir);
                                        result = SmbFileUtil.smbUploading(receipt.getAbsolutePath(),
                                                tmpByDate, FGBiz.dspCenter.dspSet.receiptShareDir);
                                    } else {
                                        tmpByDate = tmpByDate.replaceAll(reqHeader.bankCode + "/", "");
                                        WriteBankLogLn("正在上传文件至微服务:" + FGBiz.dspCenter.dspSet.receiptShareDir);
                                        Map<String, String> map = FormSubmit.fileUpload
                                                (FGBiz.dspCenter.dspSet.receiptShareDir, keys[1], receipt.getPath(), tmpByDate, receipt.getName(), getCharset());
                                        WriteBankLogStep3(JSON.toJSONString(map));
                                        if (map.keySet().size() != 0) {
                                            result = Integer.valueOf(map.get("respCode"));
                                            tmpByDate = map.get("remotePath");
                                        } else {
                                            result = -1;
                                        }
                                    }

                                    if (result == 0) {
                                        tmpFileCount++;
                                        WriteBankLogLn("文件上传成功");
                                        uploadRecord.append(keys[1] + "|" + keys[0] + "|" + receipt.getName() + "\r\n");
                                        String paths = FGBiz.dspCenter.dspSet.receiptMainDir + File.separator +
                                                "dateFile" + File.separator + bankFront.bankCode + File.separator + "receiptdateDealed" +
                                                File.separator + keys[0] + File.separator + keys[1] + "_success.txt";
                                        FileHelper.appendFile(paths, keys[1] + "|" + keys[0] + "|" + receipt.getName() + "|" + keys[3] + "\r\n", getCharset());
                                    } else {
                                        WriteBankLogLn("文件已存在共享目录无需重复上传");
                                    }
                                }
                                if (result == 0 || result == 1) {
                                    //推送数据给ATS处理
                                    json.append("{");
                                    json.append("\"actNum\":\"" + keys[1] + "\",");
                                    json.append("\"actCur\":\"" + 1 + "\",");
                                    //拼接回单编号确定唯一
                                    json.append("\"receiptCode\":\"" + keys[3] + "\",");//回单编号
                                    json.append("\"receiptType\":\"" + "" + "\",");//回单类型  1：存款回单；2：取款回单；3：转账回单；4：缴税回单；5：收费回单；6定期回单；7：活期回单
                                    json.append("\"receiptState\":\"" + "" + "\",");//回单状态 1：正常；2：冲正；3：被冲正；4：当日冲正
                                    json.append("\"oppActName\":\"" + "" + "\",");
                                    json.append("\"oppActNum\":\"" + "" + "\",");
                                    json.append("\"amount\":\"" + keys[4] + "\",");
                                    json.append("\"moneyway\":\"" + "" + "\",");
                                    json.append("\"tranSeqNo\":\"" + keys[2] + "\",");//
                                    json.append("\"tranCode\":\"" + "" + "\",");//交易码
                                    json.append("\"tranDate\":\"" + DateHelper.convertD8toD10(keys[0]) + "\",");
                                    if ("smb".equals(uploadType)) {
                                        json.append("\"filePath\":\"" + tmpByDate + receipt.getName() + "\",");//回单文件仓库存储路径
                                    } else {
                                        json.append("\"filePath\":\"" + tmpByDate + "\",");//文件路径
                                    }
                                    json.append("\"fileType\":\"2\"");
                                    json.append("},");

                                } else {
                                    WriteBankLogLn("上传文件至共享目录失败，请检查共享目录配置是否正确");
                                }
                            }
                            WriteBankLogLn("成功保存了" + tmpFileCount + "个文件,文件名为：" + uploadRecord);
                            if (tmpFileCount > 0) {
                                json.deleteCharAt(json.length() - 1);
                                json.append("]}");
                                String[] data;
                                String receiptPushType = FGBiz.dspCenter.dspSet.receiptPushType;
                                if ("nbGateway".equals(receiptPushType)) {
                                    WriteBankLogLn("3.推送给网关的数据" + json.toString());
                                    data = FormSubmit.receiptInfoSend(json.toString(), this);
                                    if (data[0].length() == 0 && data[1].equals("ok")) {
                                        WriteBankLogLn("推送数据到网关成功,请查看数据");
                                    } else {
                                        WriteBankLogLn("推送数据到网关失败");
                                    }
                                } else {
                                    WriteBankLogLn("3.推送给ATS的数据" + json.toString());
                                    data = sendToATS(json.toString());
                                    if (data[0].length() == 0 && data[1].equals("ok")) {
                                        WriteBankLogLn("推送数据到ATS成功,请查看数据");
                                    } else {
                                        WriteBankLogLn("推送数据到ATS失败");
                                    }
                                }
                            } else {
                                WriteBankLogLn("成功保存文件条数为0，不需要推送数据到ATS");
                            }
                        }
                    } else {
                        WriteBankLogLn("没有需要下载电子回单的回单号文件");
                    }

                }
            }
        } catch (Exception ex) {
            WriteBankLogLn(ex);
        }
    }

    //下载一个月的回单
    private Map<String, File> downloadReceipt(Map<String, Map<String, String[]>> receiptMap) throws Exception {
        Map<String, File> result = new HashMap<String, File>();
        for (Map.Entry<String, Map<String, String[]>> entry : receiptMap.entrySet()) {
            String key = entry.getKey();
            String[] keyInfo = key.split("_");
            Map<String, String[]> valueMap = entry.getValue();
            String paths = FGBiz.dspCenter.dspSet.receiptMainDir + File.separator +
                    "dateFile" + File.separator + bankFront.bankCode + File.separator +
                    "receiptdateDealed" + File.separator + keyInfo[0] + File.separator + keyInfo[1] + "_success.txt";
            String content = "";
            if (FileHelper.existFile(paths)) {
                content = FileHelper.readFileText(paths, getCharset());
            }
            for (Map.Entry<String, String[]> entrys : valueMap.entrySet()) {
                String[] arrValue = entrys.getValue();
                File recept = null;
                if (content.contains(entrys.getKey())) {
                    WriteBankLogLn("交易单号:" + entrys.getKey() + "的电子回单已经下载过");

                    String localfile = FGBiz.dspCenter.dspSet.receiptMainDir + File.separator + reqHeader.bankCode + File.separator + arrValue[1].substring(0, 6) +
                            File.separator + arrValue[1].substring(6, 8) + File.separator + arrValue[2]
                            + File.separator + arrValue[0] + File.separator + content.split("\\|")[2];
                    recept = new File(localfile);
                } else {
                    recept = download(arrValue);
                }

                if (recept != null) {
                    //日期_账号_原交易流水
                    result.put(arrValue[1] + "_" + arrValue[2] + "_" + arrValue[3] + "_" + arrValue[0] + "_" + arrValue[4], recept);
                }
            }
        }
        return result;
    }

    //下载单个电子回单文件
    private File download(String[] value) {

        try {
            XmlTextWriter xmlWriter = new XmlTextWriter();
            TZB01Header header = new TZB01Header();
            header.req_no = reqHeader.reqSeqID;
            header.tr_code = "544004";
            writeCommonHeader(xmlWriter, header);
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("body");
            xmlWriter.writeElementString("tran_receipt_no", value[0]);
            xmlWriter.writeEndDocument();
            int length = xmlWriter.toXmlString().getBytes(getCharset()).length + 2;
            String head = String.format("%-10s", length + "") + "00";
            String[] bankResult = sendToBank(head + xmlWriter.toXmlString());
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpbkReader = loadBankRespXmlReader(bankResult[1].substring(12), tmpSbMsg);
                if (tmpbkReader != null) {
                    String succFlag = tmpbkReader.getFirstText("/ap/head/succ_flag");
                    String retCode = tmpbkReader.getFirstText("/ap/head/ret_code");
//                    String retInfo = tmpbkReader.getFirstText("/ap/head/ret_info");
                    if ("0".equals(succFlag) && "0000".equals(retCode)) {
                        String receipt_name = tmpbkReader.getFirstText("/ap/body/file_name");

                        //交易单号|经办日期|账号|原交易流水号|交易金额|经办柜员|
                        String localfile = FGBiz.dspCenter.dspSet.receiptMainDir + File.separator + reqHeader.bankCode + File.separator +
                                value[1].substring(0, 6) + File.separator + value[1].substring(6, 8) + File.separator + value[2]
                                + File.separator + value[0];
                        String receiptDownType = getBankConfig().getValueAsString("receiptDownType");
                        if ("sftp".equals(receiptDownType)) {
                            //Sftp方式
                            SftpPortClient sftpPortClient = null;
                            try {
                                FtpSet ftpSet = bankFront.getFtpSet("receipt");
                                ftpSet.downDir = StringHelper.trimEnd(ftpSet.downDir, "/") + "/";
                                WriteBankLogLn("SFTP下载地址" + ftpSet.serverIP + ":" + ftpSet.port);

                                sftpPortClient = new SftpPortClient(ftpSet);
                                WriteBankLogLn("下载到本地目录为：" + localfile);
                                WriteBankLogLn("sftp目录下文件名为：" + receipt_name);
                                FtpReceiver ftpReceiver = sftpPortClient.downloadFileByName("", localfile, receipt_name);
                                if (ftpReceiver.isCompleted) {
                                    WriteBankLogLn("下载成功，下载路径为：" + localfile + "文件名为" + receipt_name);
                                } else {
                                    WriteBankLogLn("下载失败，文件名为" + receipt_name);
                                }
                            } catch (Exception ex) {
                                ex.printStackTrace();
                                WriteBankLogLn(ex);
                            } finally {
                                if (sftpPortClient != null) {
                                    sftpPortClient.disconnect();
                                }
                            }
                        } else if ("ftp".equals(receiptDownType)) {
                            FtpSet ftpSet = bankFront.getFtpSet("receipt");
                            FtpPortClient client = new FtpPortClient(ftpSet);
                            FtpReceiver ftpReceiver = client.downloadFile(receipt_name, localfile);
                            if (!ftpReceiver.isCompleted) {
                                WriteBankLogLn(ftpReceiver.connMsg);
                            } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
                                WriteBankLogLn("下载失败");
                            } else {
                                WriteBankLogLn("下载成功");
                            }
                        } else {
                            //共享目录方式
                            if (StringHelper.hasAnyChar(bankFront.bankReceiptMainDir)) {
                                StringBuilder smbSb = new StringBuilder();
                                SmbFileUtil.smbDownload(localfile, bankFront.bankReceiptMainDir, receipt_name, smbSb);
                            } else {
                                throw new Exception("请配置银行前置机回单目录");
                            }
                        }
                        return new File(localfile + "/" + receipt_name);
                    }
                } else {
                    WriteBankLogLn(tmpSbMsg.toString());
                }
            } else {
                WriteBankLogLn(bankResult[1]);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            WriteBankLogLn(ex);
        }
        return null;
    }
}
